package com.nycreativity.elecreativity.service.impl

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.toolkit.IdWorker
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.nycreativity.elecreativity.entity.po.OrderItem
import com.nycreativity.elecreativity.mapper.OrderMapper
import com.nycreativity.elecreativity.service.OrderService
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.nycreativity.elecreativity.entity.enums.OrderStatusEnum
import com.nycreativity.elecreativity.entity.enums.PaymentStateEnum
import com.nycreativity.elecreativity.entity.param.order.OrderAddParam
import com.nycreativity.elecreativity.entity.param.order.OrderPaymentParam
import com.nycreativity.elecreativity.entity.param.order.OrderQueryParam
import com.nycreativity.elecreativity.entity.po.Order
import com.nycreativity.elecreativity.entity.vo.PageDataVO
import com.nycreativity.elecreativity.entity.vo.order.OrderItemVO
import com.nycreativity.elecreativity.entity.vo.order.OrderOverviewVO
import com.nycreativity.elecreativity.mapper.OrderItemMapper
import com.nycreativity.elecreativity.mapper.vomapper.OrderItemVOMapper
import com.nycreativity.elecreativity.mapper.vomapper.OrderOverviewVOMapper
import com.nycreativity.elecreativity.service.ShoppingCartService
import com.nycreativity.elecreativity.util.KtWrapperUtil
import com.nycreativity.elecreativity.util.PageUtil
import com.nycreativity.elecreativity.util.usersession.UserContext
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
import javax.annotation.Resource

/**
 * <p>
 *  订单服务实现类
 * </p>
 *
 * @author sxt && ttxxi
 * @since 2021-03-11
 */
@Service
class OrderServiceImpl : ServiceImpl<OrderMapper, Order>(), OrderService {

    @Resource
    lateinit var orderMapper: OrderMapper

    @Resource
    lateinit var orderItemMapper: OrderItemMapper

    @Resource
    lateinit var orderOverviewVOMapper: OrderOverviewVOMapper

    @Resource
    lateinit var orderItemVOMapper: OrderItemVOMapper

    @Resource
    lateinit var shoppingCartService: ShoppingCartService

    @Transactional
    override fun addOrder(orderAddParams: List<OrderAddParam>): Long? {
        val user = UserContext.get() ?: return null
        if (orderAddParams.isEmpty()) {
            return null
        }
        val orderId = IdWorker.getId()
        val order = Order(
            orderId,
            user.id,
            OrderStatusEnum.WAITING_FOR_PAYMENT.status,
            LocalDateTime.now()
        )
        val list = orderAddParams.map {
            val orderItem = OrderItem(
                order.id,
                order.creator,
                it.skuId,
                it.goodsPrice,
                it.goodsCount,
                LocalDateTime.now()
            )
            order.totalAmount += orderItem.allAmount
            orderItem
        }
        val orderInsert = orderMapper.insert(order) > 0
        if (!orderInsert) {
            return null
        }
        // 批量插入为了赶进度先这样写，后期优化
        var orderItemHasInsert = true
        list.forEach {
            orderItemHasInsert = orderItemMapper.insertOrderItem(it) > 0
        }
        if (orderItemHasInsert) {
            orderAddParams.map {
                it.skuId!!
            }.toTypedArray().let { sc ->
                // 删除对应购物车信息 如果有的话
                shoppingCartService.removeShoppingCartItems(sc)
            }
            return orderId
        }
        return null
    }

    override fun queryOrderOverview(orderQueryParam: OrderQueryParam): PageDataVO<OrderOverviewVO>? {
        val user = UserContext.get() ?: return null
        val queryWrapper = KtQueryWrapper(OrderOverviewVO::class.java).eq(OrderOverviewVO::creator, user.id)
            .orderByDesc(OrderOverviewVO::createTime)
        orderQueryParam.status?.forEach { status ->
            queryWrapper.or {
                it.eq(OrderOverviewVO::status, status)
            }
        }
        val page = Page<OrderOverviewVO>(orderQueryParam.currentPage.toLong(), orderQueryParam.pageSize.toLong())
        return PageUtil.convert(orderOverviewVOMapper.selectPage(page, queryWrapper))
    }

    override fun queryOrderItems(orderId: Long): List<OrderItemVO> {
        return orderItemVOMapper.selectList(
            QueryWrapper<OrderItemVO>()
                .eq("order_id", orderId)
                .orderByDesc("create_time")
        )
    }

    @Transactional(propagation = Propagation.REQUIRED)
    override fun removeOrder(orderIds: Array<Long>): Boolean {
        if (orderIds.isEmpty()) {
            return false
        }
        val now = LocalDateTime.now()
        var rs = true
        orderIds.forEach {
            val orderWrapper = KtWrapperUtil
                .ktDeleteWrapperForUpdate<Order>(modifyTime = now)
                .eq(Order::id, it)
            rs = orderMapper.update(null, orderWrapper) > 0
            val orderItemWrapper = KtWrapperUtil
                .ktDeleteWrapperForUpdate<OrderItem>(modifyTime = now)
                .eq(OrderItem::orderId, it)
            orderItemMapper.update(null, orderItemWrapper)
        }
        return rs
    }

    override fun updateOrderPaymentInfo(param: OrderPaymentParam): Boolean {
        val order = orderMapper.selectById(param.id)
        order.paymentMethod = param.paymentMethod
        order.paymentInnerId = param.paymentInnerId
        order.status = when (param.paymentState) {
            PaymentStateEnum.WAITING_FOR_PAYMENT -> OrderStatusEnum.WAITING_FOR_PAYMENT.status
            PaymentStateEnum.HAS_PAID -> OrderStatusEnum.WAITING_FOR_DELIVER.status
            PaymentStateEnum.HAS_REFUNDED -> OrderStatusEnum.HAS_REFUNDED.status
            else -> null
        }
        return updateById(order)
    }

}
